import env from '@/config/env';
import http from "@/utils/request";
import Enum from '../uilts/enum';
import type { GenderEnum } from '../uilts/enum';

type BaseType = number | string;

export interface UserInfoInter {
    avatar: string;
    nickname: string;
    totalTime: BaseType;
    totalSign: BaseType;
    learnedNumber: BaseType;
    totalLoginDays: BaseType;
    melon_seeds: BaseType;
    debris: BaseType;
    blindVoucher: BaseType;
    idcode: BaseType;
    gender: GenderEnum;
    birthday: string;
    study: any[];
    grade: string;
    is_vip: number;
    is_login: boolean,
    headframe: {
        bg_color: string;
        bg_img: string;
        img: string;
    }
}

/**
 * 用户模块
 */
export class User {
    // 用于存储系统个人数据基本值
    private static BASE_USERINFO: UserInfoInter = {
        avatar: env.prefixUrl + 'headframe/8a6cef79b40762064bce97156f7daf6e.png',
        nickname: '奶酪',
        totalTime: '-',
        totalSign: '-',
        learnedNumber: '-',
        totalLoginDays: '-',
        melon_seeds: 0,
        debris: 0,
        blindVoucher: 0,
        idcode: 0,
        birthday: '-',
        gender: Enum.GenderEnum.MAN,
        study: [],
        grade: "",
        is_vip: 0,
        is_login: false, // 处理是否登录保存了用户信息
        headframe: {
            bg_color: '',
            bg_img: '',
            img: env.prefixUrl + 'headframe/6e5c0d525e1159625a43e2dfefefd283.png',
        }
    }

    public get USERINFO(): UserInfoInter {
        return uni.getStorageSync(Enum.STORE_KEY.USERINFO) ? JSON.parse(decodeURI(uni.getStorageSync(Enum.STORE_KEY.USERINFO))) : User.BASE_USERINFO;
    }

    public set USERINFO(user_info: UserInfoInter) {
        uni.setStorageSync(Enum.STORE_KEY.USERINFO, encodeURI(JSON.stringify(user_info)));
    }

    public get TOKEN() {
        return uni.getStorageSync(Enum.STORE_KEY.TOKEN) || '';
    }

    public set TOKEN(token: string) {
        if (token) {
            uni.setStorageSync(Enum.STORE_KEY.TOKEN, token);
        } else {
            uni.removeStorageSync(Enum.STORE_KEY.USERINFO);
            uni.removeStorageSync(Enum.STORE_KEY.TOKEN);
        }
    }

    public constructor() {

    }

    public static init() {
        User.ini2();
    }
    public static ini2() {

    }

    public async getCode() {
        return new Promise((resolve, reject) => {
            uni.login({
                provider: 'weixin', //使用微信登录
                scopes: 'auth_user',
                success: function (res) {
                    resolve(res);
                },
                fail: function (e) {
                    reject(e)
                }
            });
        });
    }

    /**
     * 手机号登录
     * @param query
     * @param callback 回调函数
     */
    public async setPhoneLogin(query: { code: string }, callback?: Function) {
        let params: { code: string, codephone: string } = {
            code: '',
            codephone: query.code
        }
        let res: any = null;
        try {
            const wxAuth: any = await this.getCode();
            params.code = wxAuth && wxAuth.code;
            res = await http.post<Post.data>("/v1/Wechatapp/mobileLogin", params);
            if (res) {
                this.TOKEN = res.token;
                await this.setUserInfo(false);
                uni.setStorageSync("idcode", res.uInfo.idcode);
            }
        } catch (e) {
            console.error(e);
        } finally {
            (callback && res) && callback(res);
        }
    }

    /**
     * 微信号登录
     * @param callback 回调函数
     */
    public async setWxLogin(callback?: Function) {
        let params: { code: string } = {
            code: '',
        }
        let res: any = null;
        try {
            const wxAuth: any = await this.getCode();
            params.code = wxAuth && wxAuth.code;
            res = await http.post<Post.data>("/v1/Wechatapp/wxlogin", params);
            if (res) {
                this.TOKEN = res.token;
                await this.setUserInfo(false);
                uni.setStorageSync("idcode", res.uInfo.idcode);
            }
        } catch (e) {
            console.error(e);
        } finally {
            (callback && res) && callback(res);
        }
    }

    /**
     * 设置用户信息
     * @param loading 是否显示loading界面
     * @param notJump 失效是否跳转首页
     * @param callback 回调函数
     */
    public async setUserInfo(loading: boolean, notJump: boolean = false, callback?: Function) {
        let res: any = null;
        try {
            res = await http.post<Post.data>("/v1/Wechatapp/uCenter", {}, {
                isLoading: loading,
                hideLoading: loading,
                notJump
            });
            res && (this.USERINFO = Object.assign({ study: res.study || [], is_login: true }, res.uInfo));
        } catch (e) {
            console.error(e);
        } finally {
            (callback && res) && callback(res);
        }
        return res;
    }

    /**
     * 檢查登錄狀態
     * @param loading 是否顯示Loading界面
     * @param notJump 用於請求api是否出錯跳轉
     */
    public async checkHasLogin(loading: boolean = true, notJump: boolean = true) {
        // 监测是否是token失效过来的是否存在
        if (uni.getStorageSync(Enum.STORE_KEY.LAPSE_TOKEN)) {
            uni.removeStorageSync(Enum.STORE_KEY.LAPSE_TOKEN);
            return false;
        }

        // 监测token是否存在
        if (!this.TOKEN) {
            return false;
        }

        // 监测微信登录态
        const wxLoginState = await checkSession();

        if (!wxLoginState) {
            this.TOKEN = '';
            return false;
        }

        // 监测token是否有效
        const checkToken = await this.setUserInfo(loading, notJump);

        //  如果token失效,移除token并返回false
        if (!checkToken) {
            this.TOKEN = '';
            return false;
        }

        return true;
        function checkSession() {
            return new Promise(resolve => {
                uni.checkSession({
                    success: () => {
                        return resolve(true)
                    },
                    fail: () => {
                        return resolve(false)
                    }
                })
            })
        }
    }

    /**
     * 退出登录
     * @param time
     */
    public loginOut(time: number = 1000) {
        this.TOKEN = '';
        uni.clearStorageSync();
        setTimeout(() => {
            uni.reLaunch({ url: '/pages/tabBar/home/index' });
        }, time);
    }
}